﻿using Newtonsoft.Json;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;
using System.Security.Cryptography;
using utils;

namespace Notication.AppCode
{
    class SendSms
    {
        /// <summary>
        /// 发送警报短信
        /// </summary>
        /// <param name="phone">手机号码</param>
        /// <param name="alarmLevel">警报等级</param>
        /// <param name="alarmName">警报名称</param>
        /// <returns></returns>
        public static async Task SendMsg(string phone,string alarmLevel,string alarmName, string name)
        {
            //必填,请参考"开发准备"获取如下数据,替换为实际值
            string apiAddress = "https://smsapi.cn-north-4.myhuaweicloud.com:443/sms/batchSendSms/v1"; //APP接入地址(在控制台"应用管理"页面获取)+接口访问URI
            string appKey = "rqn3jDxb8068SQ8N8zz9u49RL716"; //APP_Key
            string appSecret = "sF8rfynrHJEnqpZQ1PXBFsCeTzzx"; //APP_Secret
            string sender = "8822070308372"; //国内短信签名通道号或国际/港澳台短信通道号
            string templateId = "ab2490f9794c4d08a3b0bd46254c8d0a"; //模板ID

            //条件必填,国内短信关注,当templateId指定的模板类型为通用模板时生效且必填,必须是已审核通过的,与模板类型一致的签名名称
            //国际/港澳台短信不用关注该参数
            //string signature = "华为云短信测试"; //签名名称

            //必填,全局号码格式(包含国家码),示例:+86151****6789,多个号码之间用英文逗号分隔
            string receiver = phone; //短信接收人号码

            //选填,短信状态报告接收地址,推荐使用域名,为空或者不填表示不接收状态报告
            string statusCallBack = "";

            /*
             * 选填,使用无变量模板时请赋空值 string templateParas = "";
             * 单变量模板示例:模板内容为"您的验证码是${1}"时,templateParas可填写为"[\"369751\"]"
             * 双变量模板示例:模板内容为"您有${1}件快递请到${2}领取"时,templateParas可填写为"[\"3\",\"人民公园正门\"]"
             * 模板中的每个变量都必须赋值，且取值不能为空
             * 查看更多模板和变量规范:产品介绍>模板和变量规范
             */
            string templateParas = $"[\"{alarmLevel}\",\"{name}\",\"{alarmName}\"]"; //模板变量，此处以单变量验证码短信为例，请客户自行生成6位验证码，并定义为字符串类型，以杜绝首位0丢失的问题（例如：002569变成了2569）。

            try
            {
                //为防止因HTTPS证书认证失败造成API调用失败,需要先忽略证书信任问题
                HttpClient client = new HttpClient();
                ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };

                //请求Headers
                client.DefaultRequestHeaders.Add("Authorization", "WSSE realm=\"SDP\",profile=\"UsernameToken\",type=\"Appkey\"");
                client.DefaultRequestHeaders.Add("X-WSSE", BuildWSSEHeader(appKey, appSecret));
                //请求Body
                var body = new Dictionary<string, string>() {
                    {"from", sender},
                    {"to", receiver},
                    {"templateId", templateId},
                    {"templateParas", templateParas},
                    {"statusCallback", statusCallBack},
                    //{"signature", signature} //使用国内短信通用模板时,必须填写签名名称
                };

                HttpContent content = new FormUrlEncodedContent(body);

                var response = await client.PostAsync(apiAddress, content);
                Console.WriteLine($"{response.StatusCode}"); //打印响应结果码
                var res = await response.Content.ReadAsStringAsync();
                Console.WriteLine(res); //打印响应信息
            }
            catch (Exception e)
            {
                writeExceptionLogUtil.writeLogException(e,"/root/logs","Notication");
                Console.WriteLine(e.StackTrace);
                Console.WriteLine(e.Message);
            }
        }

        /// <summary>
        /// 构造X-WSSE参数值
        /// </summary>
        /// <param name="appKey"></param>
        /// <param name="appSecret"></param>
        /// <returns></returns>
        static string BuildWSSEHeader(string appKey, string appSecret)
        {
            string now = DateTime.Now.ToString("yyyy-MM-ddTHH:mm:ssZ"); //Created
            string nonce = Guid.NewGuid().ToString().Replace("-", ""); //Nonce

            byte[] material = Encoding.UTF8.GetBytes(nonce + now + appSecret);
            byte[] hashed = SHA256Managed.Create().ComputeHash(material);
            string hexdigest = BitConverter.ToString(hashed).Replace("-", "");
            string base64 = Convert.ToBase64String(Encoding.UTF8.GetBytes(hexdigest)); //PasswordDigest

            return String.Format("UsernameToken Username=\"{0}\",PasswordDigest=\"{1}\",Nonce=\"{2}\",Created=\"{3}\"",
                            appKey, base64, nonce, now);
        }
    }
}
